import React, { Component } from 'react';
import Styled from 'styled-components';
import { Input, Icon, Modal } from 'antd';
import SearchForm from '@/components/ui/SearchForm';
import Grid from '@/components/ui/Grid';

const Box = Styled.div`
.ant-input-group-addon {
  cursor: pointer;
}
`;

const ModalBox = Styled.div`
  display: flex;
  > div {
    width: 100%;
    &.multi {
      flex: 3;
      border-radius: 4px;
      border: 1px solid #CCCCCC;
      > .title {
        padding: 5px;
        margin-bottom: 20px;
        font-weight: bold;
        color: #18B582;
        border-bottom: 1px solid #CCC;
      }
    }
    &.right {
      flex: 1;
      margin-left: 10px;
      > .title {
        margin-bottom: 0;
      }
      > ul {
        height: 605px;
        padding: 0 10px;
        overflow-y: auto;
        li {
          display: flex;
          padding: 8px 0;
          align-items: center;
          border-bottom: 1px solid #e8e8e8;
          > .name {
            flex: 1;
            padding: 0 10px;
          }
          > .icon {
            width: 30px;
            color: #bfbfbf;
            cursor: pointer;
            &:hover {
              color: #18B582;
            }
          }
        }
      }
    }
  }
`;

class PopupSelect extends Component {
  constructor(props) {
    super(props);
    const { value, onChange, dataKey, dataValue, multi, onlyReturnKey, modal, grid } = props;
    this.dataKey = dataKey || 'code';
    this.dataValue = dataValue || 'name';
    const temp = this.setInitialValue(value, multi);
    if (value && onChange && onlyReturnKey) {
      onChange(multi ? temp.keys : temp.keys[0]);
    }
    this.state = {
      modalConfig: this.setModalConfig(modal),
      visible: false,
      gridSearch: grid.search,
      selectedRowKeys: temp.keys,
      selectedRows: temp.rows,
      inputValue: temp.rows
    };
    this.gridRowSelection = {
      type: multi ? 'checkbox' : 'radio',
      onChange: (selectedRowKeys, selectedRows) => {
        if (selectedRowKeys.length !== selectedRows.length) {
          const allSelectedRows = this.state.selectedRows.concat(selectedRows);
          let temp = [];
          selectedRowKeys.forEach(item => {
            temp.push(allSelectedRows.filter(i => i[this.dataKey] === item)[0]);
          });
          this.setState({ selectedRowKeys, selectedRows: temp });
        } else {
          this.setState({ selectedRowKeys, selectedRows });
        }
      }
    };
  }

  componentDidUpdate(prevProps) {
    const { value } = this.props;
    if (prevProps.value !== value && !value) {
      this.setState({ selectedRowKeys: [], selectedRows: [], inputValue: [] });
    }
  }

  setInitialValue(value, multi) {
    let rows = [];
    let keys = []
    if (value) {
      if (multi) {
        keys = value.map(i => i[this.dataKey]);
        rows = value;
      } else {
        keys = [value[this.dataKey]];
        rows = [value];
      }
    }
    return { keys, rows };
  }

  setModalConfig(modal) {
    const onOk = modal?.onOk;
    return Object.assign({
      maskClosable: false
    }, modal, {
      onOk: () => {
        this.setValue(onOk);
        this.setState({ visible: false });
      }
    });
  }

  setValue(onOk) {
    const { onChange, onlyReturnKey, multi } = this.props;
    const { selectedRowKeys, selectedRows } = this.state;
    if (onChange) {
      let value;
      if (multi) {
        value = onlyReturnKey ? selectedRowKeys : selectedRows.slice();
      } else {
        value = onlyReturnKey ? selectedRowKeys[0] : Object.assign({}, selectedRows[0]);
      }
      onChange(value);
      this.setState({ inputValue: selectedRows });
      // eslint-disable-next-line
      onOk?.(value);
    }
  }

  handleClickPopup() {
    const { value, multi } = this.props;
    const { inputValue } = this.state;
    if (value) {
      const temp = this.setInitialValue(multi ? inputValue : inputValue[0], multi);
      this.setState({ selectedRowKeys: temp.keys, selectedRows: inputValue });
    }
    this.setState({ visible: true });
  }

  handleClickRemove(e, index, isSetValue) {
    e.stopPropagation();
    const { selectedRows, selectedRowKeys } = this.state;
    selectedRowKeys.splice(index, 1);
    selectedRows.splice(index, 1);
    this.setState({ selectedRowKeys, selectedRows }, () => isSetValue && this.setValue());
  }

  renderMulti() {
    const { placeholder } = this.props;
    const { inputValue } = this.state;
    return (
      <div className="ant-select-selection ant-select-selection--multiple" onClick={this.handleClickPopup.bind(this)}>
        <div className="ant-select-selection__rendered">
          <div unselectable="on" className="ant-select-selection__placeholder" style={{display: inputValue.length ? 'none' : 'block'}}>{placeholder}</div>
          <ul>
            {inputValue.map((item, index) => (
              <li key={index} unselectable="on" className="ant-select-selection__choice" title={item[this.dataValue]}>
                <div className="ant-select-selection__choice__content">{item[this.dataValue]}</div>
                <span className="ant-select-selection__choice__remove">
                  <Icon type="close" onClick={e => this.handleClickRemove(e, index, true)} />
                </span>
              </li>
            ))}
          </ul>
        </div>
      </div>
    );
  }

  renderLeft() {
    const { gridSearch, selectedRowKeys } = this.state;
    const { formItems, grid, multi } = this.props;
    const { search, ...gridOther } = grid;
    return (
      <div className={multi ? 'multi' : ''}>
        {multi ? <div className="title">可选数据</div> : ''}
        {formItems ? <SearchForm items={formItems} fnSearch={gridSearch => this.setState({ gridSearch })} /> : ''}
        <Grid ref={grid => this.grid = grid}
          scroll={{y: 378}}
          search={gridSearch}
          rowSelection={{selectedRowKeys, ...this.gridRowSelection}}
          {...gridOther}
        />
      </div>
    )
  }

  renderRight() {
    const { selectedRows } = this.state;
    return (
      <div className="multi right">
        <div className="title">已选数据</div>
        <ul>
          {selectedRows.map((item, index) => (
            <li key={item[this.dataKey]}>
              <span className="name">{item[this.dataValue]}</span>
              <span className="icon">
                <Icon type="close-circle" theme="filled" onClick={e => this.handleClickRemove(e, index)} />
              </span>
            </li>
          ))}
        </ul>
      </div>
    )
  }

  render() {
    const { modalConfig, visible, inputValue } = this.state;
    const { icon, value, dataKey, dataValue, onlyReturnKey, multi, formItems, grid, ...params } = this.props;
    return (
      <Box className="ant-select">
        {multi ? this.renderMulti() : <Input value={inputValue[0]?.[this.dataValue]} readOnly addonAfter={<Icon type={icon || 'ellipsis'} onClick={this.handleClickPopup.bind(this)} />} {...params} />}
        <Modal {...modalConfig}
          visible={visible}
          onCancel={() => this.setState({ selectedRowKeys: [], selectedRows: [], visible: false })}
        >
        <ModalBox>
          {this.renderLeft()}
          {multi ? this.renderRight() : ''}
        </ModalBox>
        </Modal>
      </Box>
    );
  }
}      

export default PopupSelect;
